package com.ai.imagetext.service;
import com.ai.imagetext.dto.AiAnalysisResponse;
import com.ai.imagetext.entity.Image;
import com.ai.imagetext.repository.ImageRepository;
import com.ai.imagetext.util.CustomMultipartFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Classname TextGenService
 * @Date 2025/7/19 09:26
 * @Created by wangguiyou
 * @Email wgy_sdrz@icloud.com
 * @Description TODO
 */
@Service
public class TextGenService {
    private static final Logger logger = LoggerFactory.getLogger(TextGenService.class);

    @Autowired
    private DashScopeAiService dashScopeAiService;

    @Autowired
    private ImageRepository imageRepository;

    @Value("${ai.service.enabled:true}")
    private boolean aiServiceEnabled;

    private final Random random = new Random();

    // 模拟AI分析结果（作为备用）
    private final List<String> sampleDescriptions = Arrays.asList(
            "这是一张美丽的风景照片，包含山脉和天空",
            "图片显示了一个现代化的建筑物",
            "这是一张人物肖像照片",
            "图片中包含了各种食物",
            "这是一张动物的照片",
            "图片显示了城市街景",
            "这是一张花朵的特写照片"
    );

    private final List<List<String>> sampleTags = Arrays.asList(
            Arrays.asList("风景", "自然", "山脉", "天空"),
            Arrays.asList("建筑", "现代", "城市", "设计"),
            Arrays.asList("人物", "肖像", "面部", "表情"),
            Arrays.asList("食物", "美食", "餐饮", "营养"),
            Arrays.asList("动物", "宠物", "野生", "可爱"),
            Arrays.asList("街道", "城市", "交通", "建筑"),
            Arrays.asList("花朵", "植物", "自然", "色彩")
    );

    /**
     * 分析图片 - 优先使用真实AI服务
     */
    public AiAnalysisResponse analyzeImage(MultipartFile image) {
        return analyzeImage(image, null);
    }

    /**
     * 分析图片 - 带自定义提示词
     */
    public AiAnalysisResponse analyzeImage(MultipartFile image, String customPrompt) {
        if (aiServiceEnabled) {
            try {
                //logger.info("使用TrueAI_API");
                // 使用真实的AI服务
                String prompt = customPrompt != null ? customPrompt :
                        "请详细分析这张图片，包括：1. 图片的主要内容描述 2. 识别出的关键元素和标签 3. 对内容的置信度评估。请用中文回答。";

                String aiResponse = dashScopeAiService.analyzeImageWithAi(image, prompt);
                return parseAiResponse(aiResponse);

            } catch (Exception e) {
                logger.error("AI服务调用失败，使用模拟数据", e);
                return getMockAnalysisResult();
            }
        } else {
            logger.info("AI服务已禁用，使用模拟数据");
            return getMockAnalysisResult();
        }
    }

    /**
     * 纯文本AI对话
     */
    public String chatWithAi(Long imageId, String message) {
        if (aiServiceEnabled) {
            try {
                // 根据imageId从数据库获取图片信息
                Image image = imageRepository.findByIdAndIsDeletedFalse(imageId)
                        .orElseThrow(() -> new RuntimeException("图片不存在或已被删除，ID: " + imageId));
                
                // 获取图片的URL
                String imageUrl = image.getFileUrl();
                logger.info("从数据库获取到图片URL: {}", imageUrl);
                
                // 检查图片URL是否有效
                if (imageUrl == null || imageUrl.trim().isEmpty()) {
                    logger.warn("图片URL为空，imageId: {}", imageId);
                    return "抱歉，图片URL为空，无法进行AI分析。错误信息: 图片ID " + imageId + " 对应的URL为空";
                }
                
                // 带重试机制下载图片并转换为MultipartFile
                MultipartFile multipartFile = downloadImageWithRetry(imageUrl, 3);

                return dashScopeAiService.analyzeImageWithAi(multipartFile, message);
            } catch (java.io.IOException e) {
                logger.error("图片下载失败，imageId: {}, 错误: {}", imageId, e.getMessage());
                return "抱歉，无法下载图片进行AI分析。错误信息: " + e.getMessage();
            } catch (Exception e) {
                logger.error("AI对话服务调用失败，imageId: {}", imageId, e);
                return "抱歉，AI服务暂时不可用。错误信息: " + e.getMessage();
            }
        } else {
            logger.info("AI服务已禁用，返回模拟文案");
            return generateMockTextContent(message, imageId);
        }
    }

    /**
     * 从URL下载图片并转换为MultipartFile
     * @param imageUrl 图片URL
     * @return MultipartFile对象
     * @throws IOException 下载失败时抛出异常
     */
    private MultipartFile downloadImageFromUrl(String imageUrl) throws IOException {
        logger.info("开始从URL下载图片: {}", imageUrl);
        
        // 验证URL格式
        if (imageUrl == null || imageUrl.trim().isEmpty()) {
            throw new IOException("图片URL为空");
        }
        
        // 检查是否为有效的HTTP/HTTPS URL
        if (!imageUrl.toLowerCase().startsWith("http://") && !imageUrl.toLowerCase().startsWith("https://")) {
            throw new IOException("无效的图片URL格式: " + imageUrl);
        }
        
        URL url = new URL(imageUrl);
        URLConnection connection = url.openConnection();
        
        // 设置请求头，模拟浏览器访问，支持OSS等云存储
        connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
        connection.setRequestProperty("Accept", "image/webp,image/apng,image/*,*/*;q=0.8");
        connection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8");
        connection.setRequestProperty("Cache-Control", "no-cache");
        connection.setConnectTimeout(15000); // 15秒连接超时
        connection.setReadTimeout(60000);    // 60秒读取超时
        
        try (InputStream inputStream = connection.getInputStream();
             ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            
            // 检查响应状态码（如果是HttpURLConnection）
            if (connection instanceof java.net.HttpURLConnection) {
                java.net.HttpURLConnection httpConnection = (java.net.HttpURLConnection) connection;
                int responseCode = httpConnection.getResponseCode();
                if (responseCode != 200) {
                    throw new IOException("HTTP请求失败，状态码: " + responseCode + ", URL: " + imageUrl);
                }
                
                // 检查Content-Type
                String responseContentType = httpConnection.getContentType();
                if (responseContentType != null && !responseContentType.toLowerCase().startsWith("image/")) {
                    logger.warn("响应Content-Type不是图片类型: {}, URL: {}", responseContentType, imageUrl);
                }
            }
            
            byte[] buffer = new byte[8192]; // 增大缓冲区
            int bytesRead;
            long totalBytes = 0;
            long maxSize = 10 * 1024 * 1024; // 限制最大10MB
            
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                totalBytes += bytesRead;
                if (totalBytes > maxSize) {
                    throw new IOException("图片文件过大，超过10MB限制");
                }
                outputStream.write(buffer, 0, bytesRead);
            }
            
            byte[] imageBytes = outputStream.toByteArray();
            
            if (imageBytes.length == 0) {
                throw new IOException("下载的图片文件为空");
            }
            
            // 验证图片文件头
            if (!isValidImageFile(imageBytes)) {
                throw new IOException("下载的文件不是有效的图片格式");
            }
            
            // 从URL中提取文件名，如果无法提取则使用默认名称
            String fileName = extractFileNameFromUrl(imageUrl);
            
            // 根据文件内容和URL确定Content-Type
            String contentType = determineContentTypeFromBytes(imageBytes, imageUrl, fileName);
            
            logger.info("图片下载完成，大小: {} bytes, 文件名: {}, Content-Type: {}", 
                       imageBytes.length, fileName, contentType);
            
            return new CustomMultipartFile(
                "image",           // 参数名
                fileName,          // 原始文件名
                contentType,       // Content-Type
                imageBytes         // 文件内容
            );
        } catch (IOException e) {
            logger.error("图片下载失败，URL: {}, 错误: {}", imageUrl, e.getMessage());
            throw new IOException("图片下载失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 从URL中提取文件名
     */
    private String extractFileNameFromUrl(String url) {
        try {
            String path = new URL(url).getPath();
            String fileName = path.substring(path.lastIndexOf('/') + 1);
            
            // 如果文件名为空或没有扩展名，使用默认名称
            if (fileName.isEmpty() || !fileName.contains(".")) {
                return "downloaded_image.jpg";
            }
            
            return fileName;
        } catch (Exception e) {
            logger.warn("无法从URL提取文件名: {}", url, e);
            return "downloaded_image.jpg";
        }
    }
    
    /**
     * 根据URL和文件名确定Content-Type
     */
    private String determineContentType(String url, String fileName) {
        String lowerUrl = url.toLowerCase();
        String lowerFileName = fileName.toLowerCase();
        
        if (lowerUrl.contains(".png") || lowerFileName.endsWith(".png")) {
            return "image/png";
        } else if (lowerUrl.contains(".gif") || lowerFileName.endsWith(".gif")) {
            return "image/gif";
        } else if (lowerUrl.contains(".webp") || lowerFileName.endsWith(".webp")) {
            return "image/webp";
        } else {
            // 默认为JPEG
            return "image/jpeg";
        }
    }
    
    /**
     * 根据文件内容、URL和文件名确定Content-Type
     */
    private String determineContentTypeFromBytes(byte[] imageBytes, String url, String fileName) {
        // 首先通过文件头判断
        String contentTypeFromHeader = getContentTypeFromFileHeader(imageBytes);
        if (contentTypeFromHeader != null) {
            return contentTypeFromHeader;
        }
        
        // 如果无法从文件头判断，则使用URL和文件名
        return determineContentType(url, fileName);
    }
    
    /**
     * 通过文件头判断图片类型
     */
    private String getContentTypeFromFileHeader(byte[] bytes) {
        if (bytes == null || bytes.length < 4) {
            return null;
        }
        
        // JPEG: FF D8 FF
        if (bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xD8 && bytes[2] == (byte) 0xFF) {
            return "image/jpeg";
        }
        
        // PNG: 89 50 4E 47
        if (bytes[0] == (byte) 0x89 && bytes[1] == 0x50 && bytes[2] == 0x4E && bytes[3] == 0x47) {
            return "image/png";
        }
        
        // GIF: 47 49 46 38
        if (bytes[0] == 0x47 && bytes[1] == 0x49 && bytes[2] == 0x46 && bytes[3] == 0x38) {
            return "image/gif";
        }
        
        // WebP: 52 49 46 46 ... 57 45 42 50
        if (bytes.length >= 12 && 
            bytes[0] == 0x52 && bytes[1] == 0x49 && bytes[2] == 0x46 && bytes[3] == 0x46 &&
            bytes[8] == 0x57 && bytes[9] == 0x45 && bytes[10] == 0x42 && bytes[11] == 0x50) {
            return "image/webp";
        }
        
        return null;
    }
    
    /**
     * 验证是否为有效的图片文件
     */
    private boolean isValidImageFile(byte[] bytes) {
        return getContentTypeFromFileHeader(bytes) != null;
    }
    
    /**
     * 带重试机制的图片下载
     * @param imageUrl 图片URL
     * @param maxRetries 最大重试次数
     * @return MultipartFile对象
     * @throws IOException 下载失败时抛出异常
     */
    private MultipartFile downloadImageWithRetry(String imageUrl, int maxRetries) throws IOException {
        IOException lastException = null;
        
        for (int attempt = 1; attempt <= maxRetries; attempt++) {
            try {
                logger.info("尝试下载图片，第 {} 次，URL: {}", attempt, imageUrl);
                return downloadImageFromUrl(imageUrl);
            } catch (IOException e) {
                lastException = e;
                logger.warn("第 {} 次下载失败: {}", attempt, e.getMessage());
                
                if (attempt < maxRetries) {
                    // 指数退避策略：第一次重试等待1秒，第二次等待2秒
                    long waitTime = attempt * 1000L;
                    try {
                        logger.info("等待 {} 毫秒后重试...", waitTime);
                        Thread.sleep(waitTime);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new IOException("下载被中断", ie);
                    }
                }
            }
        }
        
        // 所有重试都失败了
        logger.error("图片下载失败，已重试 {} 次，URL: {}", maxRetries, imageUrl);
        throw new IOException("图片下载失败，已重试 " + maxRetries + " 次。最后一次错误: " + 
                            (lastException != null ? lastException.getMessage() : "未知错误"), lastException);
    }

    /**
     * 解析AI响应，提取结构化信息
     */
    private AiAnalysisResponse parseAiResponse(String aiResponse) {
        try {
            // 尝试从AI响应中提取结构化信息
            String description = aiResponse;
            Double confidence = extractConfidence(aiResponse);
            List<String> tags = extractTags(aiResponse);

            return new AiAnalysisResponse(description, confidence, tags);

        } catch (Exception e) {
            logger.warn("解析AI响应失败，返回原始内容", e);
            return new AiAnalysisResponse(aiResponse, 0.8, Arrays.asList("AI分析"));
        }
    }

    // 匹配格式如：置信度: 85、置信度：90%、置信度 0.75 等
    private static final Pattern CONFIDENCE_PATTERN = Pattern.compile("置信度[：:]?\\s*(\\d+(?:\\.\\d+)?%?)");

    /**
     * 从AI响应中提取置信度
     * @param response 响应内容
     * @return 提取到的置信度（范围 [0.0, 1.0]），若未找到则返回默认值 0.85
     */
    public Double extractConfidence(String response) {
        if (response == null || response.trim().isEmpty()) {
            return 0.85;
        }

        Matcher matcher = CONFIDENCE_PATTERN.matcher(response);
        if (matcher.find()) {
            String confidenceStr = matcher.group(1);
            try {
                boolean isPercent = confidenceStr.endsWith("%");
                if (isPercent) {
                    confidenceStr = confidenceStr.substring(0, confidenceStr.length() - 1);
                }

                double confidence = Double.parseDouble(confidenceStr);

                if (isPercent) {
                    confidence /= 100.0;
                }

                // 限制置信度在 [0.0, 1.0] 范围内
                if (confidence < 0.0) {
                    confidence = 0.0;
                }
                if (confidence > 1.0) {
                    confidence = 1.0;
                }

                return confidence;
            } catch (NumberFormatException e) {
                logger.warn("无法解析置信度值: {}", confidenceStr, e);
            }
        }

        // 默认置信度
        return 0.85;
    }

    // 正则表达式：匹配“标签:”或“标签：”后的内容，支持多行
    private static final Pattern TAG_PATTERN = Pattern.compile("标签[：:]?\\s*([^\\r\\n]+(?:[\\r\\n][^\\r\\n]*)*)");

    // 预定义关键词库（可替换为从外部配置或 NLP 提取）
    private static final List<String> KEYWORD_DICTIONARY = Arrays.asList(
            "风景", "建筑", "人物", "动物", "食物", "花朵", "车辆", "天空", "水", "树木"
    );

    /**
     * 从AI响应中提取标签
     * 支持格式如："标签：java, python、编程"
     */
    private List<String> extractTags(String response) {
        if (response == null || response.trim().isEmpty()) {
            return Collections.emptyList();
        }

        Matcher matcher = TAG_PATTERN.matcher(response);
        if (matcher.find()) {
            String tagString = matcher.group(1).trim();
            // 分割标签（支持逗号、顿号、空格等分隔符）
            String[] tags = tagString.split("[，,、\\s]+");
            return Arrays.stream(tags)
                    .filter(tag -> !tag.isEmpty())
                    .distinct()
                    .limit(10) // 限制最多提取10个标签
                    .collect(Collectors.toList());
        }

        // 如果没有找到明确标签，尝试从内容中提取关键词作为标签
        return extractKeywordsAsTags(response);
    }

    /**
     * 从响应中提取关键词作为标签（基于预定义关键词库）
     */
    private List<String> extractKeywordsAsTags(String response) {
        return KEYWORD_DICTIONARY.stream()
                .filter(keyword -> response.contains(keyword))
                .distinct()
                .limit(5)
                .collect(Collectors.toList());
    }

    /**
     * 获取模拟分析结果
     */
    private AiAnalysisResponse getMockAnalysisResult() {
        // 模拟AI处理时间
        try {
            Thread.sleep(1000 + random.nextInt(2000));
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        // 随机选择一个分析结果
        int index = random.nextInt(sampleDescriptions.size());
        String description = sampleDescriptions.get(index);
        List<String> tags = sampleTags.get(index);
        Double confidence = 0.7 + (random.nextDouble() * 0.3); // 70%-100%的置信度

        return new AiAnalysisResponse(description, confidence, tags);
    }

    /**
     * 生成模拟文案内容
     */
    private String generateMockTextContent(String prompt, Long imageId) {
        logger.info("生成模拟文案内容，imageId: {}, prompt: {}", imageId, prompt);
        
        // 模拟AI处理时间
        try {
            Thread.sleep(500 + random.nextInt(1500));
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        // 根据提示词类型生成不同的模拟文案
        if (prompt.contains("促销") || prompt.contains("PROMOTIONAL")) {
            return generatePromotionalContent(imageId);
        } else if (prompt.contains("描述") || prompt.contains("DESCRIPTIVE")) {
            return generateDescriptiveContent(imageId);
        } else if (prompt.contains("短文案") || prompt.contains("SHORT")) {
            return generateShortContent(imageId);
        } else if (prompt.contains("长文案") || prompt.contains("LONG")) {
            return generateLongContent(imageId);
        } else {
            return generateDefaultContent(imageId);
        }
    }

    private String generatePromotionalContent(Long imageId) {
        String[] promotionalTexts = {
            "🔥限时特惠！精选优质商品，现在下单立享8折优惠！机会难得，不容错过！",
            "💥超值推荐！品质保证，价格实惠，现在购买还送精美礼品一份！",
            "⭐️新品上市！独家优惠，前100名顾客享受特价，赶紧行动吧！",
            "🎉大促销！全场商品低至5折，优质服务，满意保证！",
            "✨精品推荐！高品质，低价格，现在购买享受VIP待遇！"
        };
        return promotionalTexts[random.nextInt(promotionalTexts.length)];
    }

    private String generateDescriptiveContent(Long imageId) {
        String[] descriptiveTexts = {
            "这是一款精心设计的产品，采用优质材料制作，工艺精湛，细节处理到位。",
            "产品展现出独特的美感和实用性，适合各种场合使用，是您的理想选择。",
            "经过严格的质量控制，这款产品具有出色的性能和持久的耐用性。",
            "设计师倾心打造，融合了现代美学与传统工艺，呈现完美品质。",
            "每一个细节都经过精心雕琢，体现了品牌对品质的执着追求。"
        };
        return descriptiveTexts[random.nextInt(descriptiveTexts.length)];
    }

    private String generateShortContent(Long imageId) {
        String[] shortTexts = {
            "品质之选，值得拥有！",
            "精致生活，从这里开始。",
            "优质产品，超值体验！",
            "匠心工艺，品质保证。",
            "时尚设计，实用至上！"
        };
        return shortTexts[random.nextInt(shortTexts.length)];
    }

    private String generateLongContent(Long imageId) {
        String[] longTexts = {
            "在这个快节奏的时代，我们为您精心挑选了这款优质产品。它不仅具有出色的功能性，更体现了现代设计的美学理念。每一个细节都经过反复打磨，确保为您带来最佳的使用体验。选择它，就是选择了品质生活的开始。",
            "这款产品凝聚了设计师的心血和工匠的技艺，从原材料的选择到最终的成品，每一个环节都严格把控。它不仅是一件实用的物品，更是一种生活态度的体现。让我们一起感受品质带来的美好，享受生活中的每一个精彩瞬间。",
            "经过市场调研和用户反馈，我们不断改进和完善这款产品。它融合了创新技术和传统工艺，既保持了经典的魅力，又具备了现代的功能。无论是日常使用还是特殊场合，它都能完美胜任，成为您生活中不可或缺的伙伴。"
        };
        return longTexts[random.nextInt(longTexts.length)];
    }

    private String generateDefaultContent(Long imageId) {
        String[] defaultTexts = {
            "这是一个精心制作的产品，具有优秀的品质和设计。",
            "我们为您推荐这款优质产品，相信它会给您带来满意的体验。",
            "经过精心挑选，这款产品将为您的生活增添色彩。",
            "品质保证，服务至上，这就是我们的承诺。",
            "选择我们，选择品质，选择美好的生活体验。"
        };
        return defaultTexts[random.nextInt(defaultTexts.length)];
    }

    // 真实的AI接口调用方法（需要配置实际的AI服务）
    /*
    public AiAnalysisResponse callRealAiApi(MultipartFile image) {
        // 这里可以集成真实的AI服务，如：
        // - OpenAI Vision API
        // - Google Cloud Vision API
        // - Azure Computer Vision API
        // - 百度AI开放平台
        // - 腾讯云AI等

        try {
            // 示例：调用外部AI API
            // String base64Image = Base64.getEncoder().encodeToString(image.getBytes());
            // HttpHeaders headers = new HttpHeaders();
            // headers.set("Authorization", "Bearer YOUR_API_KEY");
            // headers.setContentType(MediaType.APPLICATION_JSON);

            // Map<String, Object> requestBody = new HashMap<>();
            // requestBody.put("image", base64Image);

            // HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
            // ResponseEntity<AiAnalysisResponse> response = restTemplate.postForEntity(
            //     "https://api.example-ai-service.com/analyze", entity, AiAnalysisResponse.class);

            // return response.getBody();
        } catch (Exception e) {
            throw new RuntimeException("AI分析失败: " + e.getMessage());
        }
    }
    */
}
